#pragma once
#ifndef _IMAGE_PROCESS_WORKER_H_
#define _IMAGE_PROCESS_WORKER_H_
#ifdef WIN32
#pragma execution_character_set("utf-8")
#endif // WIN32

#include <QObject>
#include <QLinkedList>
#include <QMutex>
#include <QRunnable>
#include <QThread>
#include <QThreadPool>
#include <QProcess>
#include <QDebug>
#include "MyModel.h"
#include "MyError.h"
#include "utils.h"
#include <imageUtils.h>
#include <qthreadpool.h>
#include<pcl/filters/statistical_outlier_removal.h>
#include <QVTKOpenGLNativeWidget.h>            //窗口显示使用
#include <pcl/visualization/pcl_visualizer.h>
#include<pcl/io/pcd_io.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <pcl/filters/voxel_grid.h>
#include<pcl/common/centroid.h>
#include<pcl/common/common.h>

struct staticalParameters {

	float maxZ = 0.0;

	float minZ = 0.0;

	float meanZ = 0.0;

	float stdZ = 0.0;

};

/// <summary>
/// 计算单帧图像上的数据的工作类
/// </summary>
class ImageProcessWorker : public QObject {

	Q_OBJECT

signals:

	/// <summary>
	/// 上传检测结果
	/// </summary>
	// void processFinished(cv::Mat& result);
	// void processFinished(vector<cv::Vec3f>& tmp_data);
	void processFinished(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,staticalParameters data);

public:

	/// <summary>
	/// 创建新线程
	/// </summary>
	/// <param name="dataList"></param>
	/// <param name="parent"></param>
	ImageProcessWorker(int rows, int cols, const ImageProcessConfig& imageProCig,const caliParam& calibration, QObject* parent = nullptr);

	~ImageProcessWorker();

	/// <summary>
	/// 处理帧数据
	/// </summary>
	/// <param name="threadPool">用于异步执行数据计算的线程池</param>
	/// <param name="data"></param>
	/// <returns>返回True表示所有帧已经处理完成</returns>
	void processFrameData(QThreadPool& threadPool, int num, cv::Mat& frame);

	/// <summary>
	/// 添加检测结果数据
	/// </summary>
	/// <param name="num"></param>
	/// <param name="result"></param>
	void addProcessResult(int num, vector<cv::Vec3f>& result);

	void addProcessResult(int num, vector<float>& result);

	// 计算 X 和 Z 的函数
	void calculateXZ(const vector<double>& aCoeffs, const vector<double>& bCoeffs, float u, float v, float& X, float& Z);

	void  getReconstructionData(int num, vector<cv::Point2f>& results);

	const MyError& getError() const;

	cv::Point3f pixelToUnitRay(const cv::Point2f& pixel, const cv::Mat& intrinsic);

	//点云数据滤波
	void cloudFilter(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud);

	/// <summary>
	/// 计算点云Z轴统计量
	/// </summary>
	/// <param name="cloud">输入的点云数据</param>
	/// <param name="maxZ">点云数据中的最大Z值</param>
	/// <param name="minZ">点云数据中的最小Z值</param>
	/// <param name="meanZ">点云数据中的Z均值</param>
	/// <param name="stdZ">点云数据中Z值的标准差</param>
	void calculateZStatistics(pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud, staticalParameters& param);

	/// <summary>
	/// 将点云数据转换为高度图
	/// </summary>
	/// <param name="cloud">输入点云数据</param>
	/// <param name="resolution"></param>
	/// <param name="use_max_height"></param>
	/// <returns></returns>
	cv::Mat pointCloudToHeightMap(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,float resolution = 1.0f,bool use_max_height = true);

	/// <summary>
	/// 将点云数据转换为高度图
	/// </summary>
	cv::Mat convertToHeightMap(const std::vector<std::vector<cv::Point3f>>& all_center_points);

private:

	//处理过程中遇到的错误信息
	MyError m_error;

	vector<vector<cv::Point2f>>all_center_points;

	// 检测深度图
	cv::Mat m_result;

	//防止向m_result中插入数据时的线程不安全问题
	QMutex m_mutex;

	int m_processCount = 0;             // 已经接收到的图像数量

	map<int, vector<cv::Point2f>> map_id_line_pixels;

	ImageProcessConfig m_imgproconfig;  // 图像处理信息

	std::vector<cv::Vec3f> m_pointCloudAccumulated;         // 点云数据

	caliParam m_calibration;  // 相机标定参数

	cv::Mat m_cam_intrinsic;  // 相机内参矩阵

	cv::Mat m_cam_discoeffs;  // 相机畸变系数

	cv::Mat m_step;//步长参数

	float YD;//Y轴方向移动步长
private:

	/// <summary>
	/// 分析单帧图像的线程, 添加到线程池中
	/// </summary>
	class Worker : public QRunnable {

	/*signals:
		void frameProcessed(const std::vector<cv::Vec3f>& pointCloud);*/
	public:

		Worker(int num, cv::Mat& frame, ImageProcessWorker* parent);

		~Worker();

	protected:

		void run();

	private:

		int m_num;							    	// 处理的图像编号

		ImageProcessWorker* m_parent = nullptr;     // 创建线程的对象

		cv::Mat m_frame;							// 处理的当前帧

		ImageProcessConfig m_inter_imgproconfig;    // 处理图像的信息

		// pcl::PointXYZ point;                        // 点云数据
	};
};


#endif // !_IMAGE_PROCESS_WORKER_H_




